package com.mandao.oneplat.boot.mvc.view;

import com.mandao.oneplat.boot.OnePlatConfig;
import com.mandao.oneplat.boot.context.OneContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.FileTemplateResolver;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Locale;

/**
 * Created by sunson on 2017/3/21.
 */
public class OneViewResolver {

    private final static String ROUTE_DEFAULT = "default/";
    private final static String ROUTE_MOBILE = "mobile/";

    private Logger logger = LoggerFactory.getLogger(getClass());

    private OnePlatConfig oneOption;
    private FileTemplateResolver themeTemplateResolver;
    private TemplateEngine themeTemplateEngine;
    private TemplateEngine assetsTemplateEngine;

    public OneViewResolver(OnePlatConfig oneOption) throws IOException {
        this.oneOption = oneOption;
        //
        logger.info("初始化主题模板引擎-开始");
        initThemeTemplateEngine();
        logger.info("初始化主题模板引擎-结束");
        //
        logger.info("初始化静态资源引擎-开始");
        initAssetsTemplateEngine();
        logger.info("初始化静态资源引擎-结束");
    }

    void initThemeTemplateEngine() {
        if (themeTemplateEngine != null) return;
        themeTemplateResolver = new FileTemplateResolver();
        themeTemplateResolver.setSuffix(oneOption.getTemplateSuffix());
        themeTemplateResolver.setCacheable(oneOption.isTemplateCacheable());
        themeTemplateEngine = new TemplateEngine();
        themeTemplateEngine.setTemplateResolver(themeTemplateResolver);
    }

    void initAssetsTemplateEngine() throws IOException {
        if (assetsTemplateEngine != null) return;
        FileTemplateResolver templateResolver = new FileTemplateResolver();
        templateResolver.setPrefix(oneOption.getBaseDir() + File.separator + oneOption.getTemplatePrefix());
        templateResolver.setCacheable(oneOption.isTemplateCacheable());
        assetsTemplateEngine = new TemplateEngine();
        assetsTemplateEngine.setTemplateResolver(templateResolver);
    }

    public void resolveAssetsView(OneContext oneContext, Writer contentWriter) {
        String viewName = oneContext.getOneView().getViewName();
        try {
            assetsTemplateEngine.process(routeTheme(oneContext.getOneRequest().isMobile()) + viewName,
                    new Context(),
                    contentWriter);
        } catch (Exception e) {
            try {
                contentWriter.write("Page Not Found.[404]");
                contentWriter.flush();
            } catch (IOException e1) {
                logger.error("模板输出异常初始化异常", e1);
            }
        }
    }

    /**
     * @param oneContext
     * @param contentWriter
     */
    public void revoleThemeView(OneContext oneContext, Writer contentWriter) {
        String lang = oneContext.getOneRequest().getLang();
        if (StringUtils.isEmpty(lang)) {
            lang = "zh";
        }
        try {
            themeTemplateResolver.setPrefix(oneOption.getBaseDir()
                    + File.separator + oneOption.getTemplatePrefix()
                    + File.separator + routeTheme(oneContext.getOneRequest().isMobile()));
            themeTemplateEngine.process(oneContext.getOneView().getViewName(),
                    new Context(new Locale(lang), oneContext.getOneModel().getModels()),
                    contentWriter);
        } catch (Exception e) {
            try {
                contentWriter.write("Page Not Found.[404]");
                contentWriter.flush();
            } catch (IOException e1) {
                logger.error("模板输出异常初始化异常", e1);
            }
        } finally {
            themeTemplateResolver.setPrefix(oneOption.getBaseDir() + File.separator + oneOption.getTemplatePrefix());
        }
    }

    String routeTheme(boolean isMobile) {
        if (!oneOption.isResponsiveMode() && isMobile) {
            return ROUTE_MOBILE;
        }
        return ROUTE_DEFAULT;
    }
}
